/**
* @file         checksum.c
* @author       bin (https://ay123.net)
* @brief        Utility to caculate checksum
* @version      0.1
* @date         2021-10-13
*
* @copyright    Copyright (c) 2021
*
* @History      First create.
*
*/

#include <stdio.h>
#include <stdlib.h>

//
// Avoid VS build fail
//
#pragma warning(disable:4996)

//
// Message string define
//
#define  STRING_PARAM_ERROR             "Parameter error!\n\r"
#define  STRING_FILE_OPEN_FAILED        "File open failed!\n\r"
#define  STRING_FILE_READ_FAILED        "File read failed!\n\r"
#define  STRING_ALLOCATE_MEM_FAILED     "Allocate memmory failed!\n\r"

#define  STRING_CHECKSUM                "%010X\n\r"
#define  STRING_FILE_OPEN_MODE          "rb+"


int main(int argc,  char ** argv)
{
	FILE                 * fp;
	unsigned char        * file_buffer;
	unsigned int           file_size;
	unsigned long int      checksum;
	unsigned long int      index;

	if (argc != 2)
	{
		printf(STRING_PARAM_ERROR);
		return 0;
	}

	fp = fopen(argv[1], STRING_FILE_OPEN_MODE);
	
	if (fp == NULL) {
		printf(STRING_FILE_OPEN_FAILED);
		return 0;
	}
	//
	// Get file size
	//
	fseek(fp, 0, SEEK_END);
	file_size = ftell(fp);

	//
	// Set file pointer to file header
	//
	rewind(fp);

	//
	// Allocate memory
	//
	file_buffer = malloc(file_size);
	if (file_buffer == NULL) {
		printf(STRING_ALLOCATE_MEM_FAILED);
		return 0;
	}

	//
	// Read file data  to buffer
	//
	if (fread(file_buffer, file_size, 1, fp) != 1) 
	{
		printf(STRING_FILE_READ_FAILED);
		return 0;
	}

	//
	// Calculate the cumulative sum
	//
	for (index = 0, checksum = 0; index < file_size; index++)
	{
		checksum += file_buffer[index] & 0xFF;
	}

	//
	// Output result
	//
	printf(STRING_CHECKSUM, checksum);

	//
	// Close file stream
	//
	fclose(fp);
	
	//
	// Free resource
	//
	free(file_buffer);

	return 0;
}